Skip to content

feat: Add Gitea commit endpoints (getCommit, getLatestCommit)#66

Open
jaysomani wants to merge 5 commits intoutopia-php:mainfrom
jaysomani:feat/gitea-commit-endpoints
Open

feat: Add Gitea commit endpoints (getCommit, getLatestCommit)#66
jaysomani wants to merge 5 commits intoutopia-php:mainfrom
jaysomani:feat/gitea-commit-endpoints

Conversation

@jaysomani
Copy link
Contributor

@jaysomani jaysomani commented Mar 1, 2026

Changes

Implements commit-related endpoints for Gitea adapter to match GitHub functionality.

Methods Implemented

  • getCommit(owner, repo, commitHash) - Fetches details of a specific commit by SHA
  • getLatestCommit(owner, repo, branch) - Fetches the most recent commit of a branch

Tests Added

  • testGetCommit - Verifies commit details retrieval
  • testGetLatestCommit - Verifies latest commit fetching
  • testGetCommitWithInvalidSha - Tests error handling for invalid commit SHA
  • testGetLatestCommitWithInvalidBranch - Tests error handling for non-existent branch
  • testGetCommitVerifyMessageContent - Verifies custom commit messages are preserved

All tests follow the established pattern with proper setup/teardown and edge case coverage.

Summary by CodeRabbit

  • New Features

    • Fetch commit details: retrieve a specific commit by hash and fetch the latest commit for any branch, returning normalized commit metadata (author, message, hash, URLs, avatar).
    • Improved error handling and validation for invalid commit SHAs and non-existent branches.
  • Tests

    • Added end-to-end tests covering commit retrieval, content verification, and error cases for invalid SHAs and branches.

@coderabbitai
Copy link

coderabbitai bot commented Mar 1, 2026

Warning

Rate limit exceeded

@jaysomani has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 24 minutes and 20 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 81e6419 and 0552bea.

📒 Files selected for processing (2)
  • src/VCS/Adapter/Git/Gitea.php
  • tests/VCS/Adapter/GiteaTest.php

Walkthrough

Two public methods were added to the Gitea VCS adapter: getCommit(string $owner, string $repositoryName, string $commitHash): array which calls /repos/{owner}/{repositoryName}/git/commits/{commitHash}, and getLatestCommit(string $owner, string $repositoryName, string $branch): array which calls /repos/{owner}/{repositoryName}/commits?sha=<branch>&limit=1. Both use Authorization headers, validate 4xx/5xx responses and expected payload structures, extract nested fields (author, committer, commit message, commit hash, URLs, avatar) and return normalized arrays. Tests were added for success and failure scenarios for each method.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary change: adding two new Gitea commit endpoint methods (getCommit and getLatestCommit) that align with the PR's core objective.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/VCS/Adapter/Git/Gitea.php`:
- Line 410: The branch value is interpolated directly into the commit URL and
can contain query-significant characters; update the URL construction in
Gitea.php so the branch is URL-encoded (e.g., replace "{$branch}" with
rawurlencode($branch)) or build the query with
http_build_query(['sha'=>$branch,'limit'=>1]) and append that to
"/repos/{$owner}/{$repositoryName}/commits" so $url is safe; modify the
assignment to $url accordingly (referencing the $url variable and $branch).

In `@tests/VCS/Adapter/GiteaTest.php`:
- Around line 420-438: The two tests testGetCommitWithInvalidSha and
testGetLatestCommitWithInvalidBranch create repositories via
$this->vcsAdapter->createRepository(...) but never delete them on the exception
path; wrap the assertions that call $this->vcsAdapter->getCommit(...) and
$this->vcsAdapter->getLatestCommit(...) in try/finally blocks that always call
the cleanup method (e.g. $this->vcsAdapter->deleteRepository(self::$owner,
$repositoryName)) in the finally so the repositoryName created in each test is
removed regardless of the thrown exception.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 92a1650 and d54667d.

📒 Files selected for processing (2)
  • src/VCS/Adapter/Git/Gitea.php
  • tests/VCS/Adapter/GiteaTest.php

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d54667d93b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds commit-retrieval support to the Gitea VCS adapter to align with the existing GitHub adapter, along with new integration tests that exercise commit fetching and error paths.

Changes:

  • Implement getCommit(owner, repo, commitHash) in the Gitea adapter.
  • Implement getLatestCommit(owner, repo, branch) in the Gitea adapter.
  • Add PHPUnit integration tests covering commit retrieval and invalid SHA/branch handling.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
src/VCS/Adapter/Git/Gitea.php Adds Gitea implementations for getCommit and getLatestCommit.
tests/VCS/Adapter/GiteaTest.php Adds integration tests validating commit retrieval and error handling scenarios.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Meldiron Meldiron added the test Enables E2E tests in CI/CD label Mar 1, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/VCS/Adapter/GiteaTest.php (1)

366-390: Always guarantee repository cleanup in happy-path commit tests.

These tests delete repositories only at the end. If an assertion or API call fails earlier, cleanup is skipped and can leak test resources across runs. Wrap test bodies in try/finally and keep deleteRepository(...) in finally.

♻️ Suggested pattern
 public function testGetCommit(): void
 {
     $repositoryName = 'test-get-commit-' . \uniqid();
     $this->vcsAdapter->createRepository(self::$owner, $repositoryName, false);

-    $this->vcsAdapter->createFile(self::$owner, $repositoryName, 'README.md', '# Test Commit');
-
-    $latestCommit = $this->vcsAdapter->getLatestCommit(self::$owner, $repositoryName, 'main');
-    $commitHash = $latestCommit['commitHash'];
-
-    $result = $this->vcsAdapter->getCommit(self::$owner, $repositoryName, $commitHash);
-
-    $this->assertIsArray($result);
-    $this->assertArrayHasKey('commitHash', $result);
-    $this->assertArrayHasKey('commitMessage', $result);
-    $this->assertArrayHasKey('commitAuthor', $result);
-    $this->assertArrayHasKey('commitUrl', $result);
-    $this->assertArrayHasKey('commitAuthorAvatar', $result);
-    $this->assertArrayHasKey('commitAuthorUrl', $result);
-
-    $this->assertSame($commitHash, $result['commitHash']);
-    $this->assertNotEmpty($result['commitMessage']);
-
-    $this->vcsAdapter->deleteRepository(self::$owner, $repositoryName);
+    try {
+        $this->vcsAdapter->createFile(self::$owner, $repositoryName, 'README.md', '# Test Commit');
+        $latestCommit = $this->vcsAdapter->getLatestCommit(self::$owner, $repositoryName, 'main');
+        $commitHash = $latestCommit['commitHash'];
+        $result = $this->vcsAdapter->getCommit(self::$owner, $repositoryName, $commitHash);
+
+        $this->assertIsArray($result);
+        $this->assertArrayHasKey('commitHash', $result);
+        $this->assertArrayHasKey('commitMessage', $result);
+        $this->assertArrayHasKey('commitAuthor', $result);
+        $this->assertArrayHasKey('commitUrl', $result);
+        $this->assertArrayHasKey('commitAuthorAvatar', $result);
+        $this->assertArrayHasKey('commitAuthorUrl', $result);
+        $this->assertSame($commitHash, $result['commitHash']);
+        $this->assertNotEmpty($result['commitMessage']);
+    } finally {
+        $this->vcsAdapter->deleteRepository(self::$owner, $repositoryName);
+    }
 }

Also applies to: 392-414, 444-457

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/VCS/Adapter/GiteaTest.php` around lines 366 - 390, Wrap the body of the
testGetCommit method in a try/finally so deleteRepository(self::$owner,
$repositoryName) always runs; specifically, after creating $repositoryName and
before any assertions/calls (i.e., around calls to createFile, getLatestCommit,
getCommit and assertions), place the assertions and API calls in the try block
and move the existing deleteRepository call into the finally block to guarantee
cleanup even if an assertion or API call throws. Apply the same try/finally
pattern to the other tests referenced (lines noted: the tests around 392-414 and
444-457) that currently call deleteRepository only at the end.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/VCS/Adapter/GiteaTest.php`:
- Around line 366-390: Wrap the body of the testGetCommit method in a
try/finally so deleteRepository(self::$owner, $repositoryName) always runs;
specifically, after creating $repositoryName and before any assertions/calls
(i.e., around calls to createFile, getLatestCommit, getCommit and assertions),
place the assertions and API calls in the try block and move the existing
deleteRepository call into the finally block to guarantee cleanup even if an
assertion or API call throws. Apply the same try/finally pattern to the other
tests referenced (lines noted: the tests around 392-414 and 444-457) that
currently call deleteRepository only at the end.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d54667d and 698def7.

📒 Files selected for processing (2)
  • src/VCS/Adapter/Git/Gitea.php
  • tests/VCS/Adapter/GiteaTest.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/VCS/Adapter/Git/Gitea.php

@Meldiron Meldiron added test Enables E2E tests in CI/CD and removed test Enables E2E tests in CI/CD labels Mar 3, 2026
$this->assertArrayHasKey('commitAuthorUrl', $result);

$this->assertNotEmpty($result['commitHash']);
$this->assertNotEmpty($result['commitAuthor']);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above - assertHasKey and assertEmpty are most minimal assertions - everytime we can assert value, we should.

For example here I would assertSame for commit hash, message, and author (author only if possible, not sure)

Comment on lines +444 to +456
public function testGetCommitVerifyMessageContent(): void
{
$repositoryName = 'test-commit-message-' . \uniqid();
$this->vcsAdapter->createRepository(self::$owner, $repositoryName, false);

$customMessage = 'Custom commit message';
$this->vcsAdapter->createFile(self::$owner, $repositoryName, 'README.md', '# Test', $customMessage);

$latestCommit = $this->vcsAdapter->getLatestCommit(self::$owner, $repositoryName, 'main');

$this->assertStringContainsString($customMessage, $latestCommit['commitMessage']);

$this->vcsAdapter->deleteRepository(self::$owner, $repositoryName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can remove this test, and ensure message (as well as author maybe) in other tests.

Also assertStringContainsString is a bit loose, I would go for assertSame.

--

I think you did this after our discussion about separating tests. Over-separation can be problem too - what helps me decide in most scenarios is to always look from perspective of action I am doing in the test, not from perspective of assertions.

Here, action in same as one in testGetLatestCommit - preparing a file with a message in commit. So I would keep it as part of same test.

If there was some extra setup (like more repositories, or more commits), or the flow had multiple steps (like ensuring it's 2nd createFile, not 1st), thats when separate test would make sense to me.

Open to discuss this further if you have strong opinion on this. I am going off of my experience with testing, so I might be missing something too

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/VCS/Adapter/Git/Gitea.php (2)

422-424: Split HTTP-failure vs payload-shape errors.

Line 422 currently throws the same message for both transport/status failures and malformed/empty payloads, which makes debugging harder.

🛠️ Proposed improvement
-        if ($statusCode >= 400 || empty($response['body'][0])) {
-            throw new Exception("Latest commit response is missing required information.");
-        }
+        if ($statusCode >= 400) {
+            throw new Exception("Failed to fetch latest commit for branch '{$branch}': HTTP {$statusCode}");
+        }
+        if (empty($response['body'][0])) {
+            throw new Exception("Latest commit response is missing required information.");
+        }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/VCS/Adapter/Git/Gitea.php` around lines 422 - 424, The current check
conflates HTTP transport/status errors and malformed payloads; update the logic
in Gitea (the method using $statusCode and $response) to throw two distinct
exceptions: if ($statusCode >= 400) throw an Exception that includes the HTTP
status code and response body/details (e.g. "Failed to fetch latest commit: HTTP
{status} - {body}"), otherwise if (empty($response['body'][0])) throw a
different Exception clearly stating the payload is missing required commit info
(e.g. "Latest commit response missing required information"), so callers can
distinguish transport errors from payload-shape errors.

391-391: Remove unused local $committer.

Line 391 assigns $committer but it is never used in the return statement, which adds noise and triggers static-analysis warnings.

♻️ Proposed cleanup
-        $committer = $body['committer'] ?? [];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/VCS/Adapter/Git/Gitea.php` at line 391, The local variable $committer in
src/VCS/Adapter/Git/Gitea.php is assigned but never used; remove the unnecessary
assignment "$committer = $body['committer'] ?? [];" (or, if committer data is
actually required, include it in the return structure where other $body fields
are returned) to eliminate dead code and static-analysis warnings—look for the
assignment in the Git/Gitea adapter function that processes the incoming $body
and either delete that line or wire $committer into the returned payload.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/VCS/Adapter/Git/Gitea.php`:
- Around line 422-424: The current check conflates HTTP transport/status errors
and malformed payloads; update the logic in Gitea (the method using $statusCode
and $response) to throw two distinct exceptions: if ($statusCode >= 400) throw
an Exception that includes the HTTP status code and response body/details (e.g.
"Failed to fetch latest commit: HTTP {status} - {body}"), otherwise if
(empty($response['body'][0])) throw a different Exception clearly stating the
payload is missing required commit info (e.g. "Latest commit response missing
required information"), so callers can distinguish transport errors from
payload-shape errors.
- Line 391: The local variable $committer in src/VCS/Adapter/Git/Gitea.php is
assigned but never used; remove the unnecessary assignment "$committer =
$body['committer'] ?? [];" (or, if committer data is actually required, include
it in the return structure where other $body fields are returned) to eliminate
dead code and static-analysis warnings—look for the assignment in the Git/Gitea
adapter function that processes the incoming $body and either delete that line
or wire $committer into the returned payload.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 698def7 and 81e6419.

📒 Files selected for processing (2)
  • src/VCS/Adapter/Git/Gitea.php
  • tests/VCS/Adapter/GiteaTest.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/VCS/Adapter/GiteaTest.php

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test Enables E2E tests in CI/CD

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants